package util;

import cn.hutool.core.io.FileUtil;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.regex.Pattern;

public class ImageHandle {
    private ImageHandle() {}

    /**
     *
     * @param src 源图片路径，支持相对路径
     * @param dest 目标图片文件夹名，支持相对路径
     * @param rows 切图行数
     * @param cols 切图列数
     * @param width 整图目标宽度
     * @param height 整图目标高度
     * 用于将一张图片拷贝到目标目录并重命名为whole.<图片类型>，并切分为rows 行 cols 列的小图片，按照1.<图片类型>，2.<图片类型>，3.<图片类型>...储存到该目录下
     */
    public static void splitImage(String src, String dest, int rows, int cols, int width, int height) {
        if (rows <= 0 || cols <= 0) {
            throw new RuntimeException("行数或列数不能小于1！");
        }
        File file = new File(src);

        if (!file.exists()) {
            return;
        }

        // 创建目标目录（如果不存在）
        File destDir = new File(dest);
        if (!destDir.exists()) {
            boolean mkStatus = destDir.mkdirs();
            if (!mkStatus) {
                throw new RuntimeException("创建目标目录失败！");
            }
        }

        File[] oldFiles = destDir.listFiles();
        if (oldFiles != null) {
            for (File oldFile : oldFiles) {
                boolean deleteStatus = oldFile.delete();
                if (!deleteStatus) {
                    throw new RuntimeException("删除旧文件失败！");
                }
            }
        }

        String extName = FileUtil.extName(src);

        try {
            BufferedImage srcImage = ImageIO.read(file);
            // 调整原图到目标尺寸
            BufferedImage resizedImage = resizeImage(srcImage, width, height);

            // 保存调整尺寸后的整图（而不是复制原始文件）
            File wholeImageFile = new File(dest, "whole." + extName);
            ImageIO.write(resizedImage, extName, wholeImageFile);

            int smallWidth = width / cols;
            int smallHeight = height / rows;

            int count = 0;
            for (int x = 0; x < rows; x++) {
                for (int y = 0; y < cols; y++) {
                    count++;
                    BufferedImage subImage = resizedImage.getSubimage(y * smallWidth, x * smallHeight, smallWidth, smallHeight);
                    File outputFile = new File(dest, count + "." + extName);
                    ImageIO.write(subImage, extName, outputFile);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("图片处理失败", e);
        }
    }

    /**
     * 更好地调整图片尺寸，保持图片质量
     * @param originalImage 原始图片
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 调整尺寸后的图片
     */
    private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = resizedImage.createGraphics();

        // 设置渲染提示以提高图像质量
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 绘制调整尺寸后的图像
        g.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        g.dispose();

        return resizedImage;
    }

    /**
     *
     * @param srcDir 源图片文件夹路径，支持相对路径
     * @param destDir 目标图片文件夹路径，支持相对路径
     * @param rows 切图行数
     * @param cols 切图列数
     * @param width 整图目标宽度
     * @param height 整图目标高度
     * 用于将源图片文件夹中的所有图片都进行切图处理
     */
    public static void splitImages(String srcDir, String destDir, int rows, int cols, int width, int height) {
        File srcFile = new File(srcDir);
        if (!srcFile.exists()) {
            return;
        }
        File[] files = srcFile.listFiles();
        int count = 0;
        if (files != null) {
            for (File file : files) {
                splitImage(file.getAbsolutePath(), destDir + "/" + ++count, rows, cols, width, height);
            }
        }
    }

    /**
     * 获取图片类型
     * @param files 接收文件数组
     * @param baseName 文件基本名
     * @return 当文件数组中存在以baseName为基本名的图片时返回图片类型，否则返回null
     */
    public static String getImageType(File[] files, String baseName) {
        if (files == null || baseName == null) {
            return null;
        }

        for (File file : files) {
            String fileName = file.getName();
            // 使用正则表达式匹配文件名和扩展名
            if (fileName.matches("^" + Pattern.quote(baseName) + "(?:\\.(.+))?$")) {
                // 提取扩展名
                int dotIndex = fileName.lastIndexOf('.');
                if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
                    return fileName.substring(dotIndex + 1);
                }
                return null;
            }
        }
        return null;
    }
}
